/** Projectile object class that has
 * fields for all of the attributes
 * that the Projectile will need.
 * Also has a reverse field
 * for reversing the sprite.
 * 
 * 
 * @author Andrew
 * @creator David - the parts for two player
 * 			Andrew - the rest
 * 		    
 * LAST UPDATED - Andrew 2/4/12
 */

public class ProjectileObject extends Object {
    
    // Standard sprite
    private String sprite = "projectile.png";
    
    // Angle with which the projectile was fired
    private double angle;
    
    // Velocity with which the projectile was fired
    private double vel;
    
    // Time (for now its just an increasing number)
    private double t = 0;
    
    // gravity
    private double g = 0.05;
    
    // Initial x position
    private double xi;
    
    // Initial y position
    private double yi;
    
    // Strength of the wind
    private double wind;
    
    // Health
    private int health;
    
    // Crash sound
    private Sound crash;
    
    // dead
    private boolean alive;
    
    // Whos turn is it? -1 is player, 1 is AI (or other player)
    private int who;
    
    
    // create a new projectile, starting from x,y with picture
    // sprite, velocity v and angle.
  public ProjectileObject(double x, double y, double v, double angler, double windr) {
      super((new Sprite("projectile.png")),x,y);
      this.vel = v;
      this.angle = angler; // Convert to radians for Math.trig
      this.xi = x;
      this.yi = y;
      this.wind = windr;
      this.health = 4;
      this.alive = true;
      this.crash = new Sound("crash.ogg");
      this.who = -1;
  }
  
  // Depending on the ammo type, change the picture
  
  public void changeAmmo(int n) {
	  String path = "projectile.png";
	  if(n == 3) path = "cat.png";
	  else if(n == 2) path = "projectile3.png";
	  else if(n == 1) path = "projectile2.png";
	  super.sprite = new Sprite(path);
  }
 
  // make it alive
  public void setAlive(boolean b) {
	  this.health = 4;
	  this.alive = b;
  }
  
  // is it alive?
  public boolean getAlive() {
	  return this.alive;
  }
  
  // change its health by n
  public void changeHealth(int n) {
	  this.health -= n;
	  if(this.health <= 0) {
		  this.alive = false;
		  reset();
		  crash.play();
	  }
  }
  
  // Trajectory Equation linking X position with time
  // NOW INCLUDES WIND as a force varying with time.
  // Return depends on player turn, as trajectory changes
  private double trajectoryX(double v,double t,double windr) {
      double output = (v * t)- (windr * t / 10);
      if(who == -1) return output;
      else return -output;
  }
    
  // Trajectory Equation for Y position as a function of time
  private double trajectoryY(double v, double t, double g) {
      double output = (v * t) - (1 * g * t * t);
      return output;
  }
  
  // Calculates the next position, moves, draws and then increases time.
  public void update() {
      // Velocity in x (angle to radian conversion)
      double velX = vel * Math.cos(angle * 0.0174532925);
      // Velocity in y
      double velY = vel * Math.sin(angle * 0.0174532925);
      
      // Set the new x and y positions relative to the 
      // Starting point
      setX((trajectoryX(velX,t,wind) + xi));
      setY(trajectoryY(velY,t,g) + yi);
      
      // increase time by 1 - old but works ok now that the frame rate is limited
      this.t = t + 1;
      // draw the projectile in its new position.
      this.draw();
  }
  
  
  // Sets the x position of the projectile
  public void setX(double n) {
      x = n;
  }
  
  // Sets the y position of the projectile
  public void setY(double n) {
      this.y = n;
  }
  
  
  // Resets the missiles time value to 0,
  // its x and y positions back to 0
  public void reset() {
      this.t = 0;
      super.x = xi;
      super.y = yi;
  }

  // Sets the projectiles velocity at which it was fired
  public double setVelocity(double v) {
      this.vel = v;
      return v;
  }
  
  // Increases time manually
  public void increaseTime() {
      t = t+1;
  }
  
  // Returns the objects current time
  public double getTime() {
      return t;
  }
  
  // Sets the Angle at which it was fired
  public void setAngle(double angle) {
      this.angle = angle;
  }
  
  // checks for collisions, then works out whos health to change, what tiles to blow up and what to give the AI
  // Only for the AI.java not peaks AI2.java
  public void checkCollAI(TankObject you,TankObject target, Map tiles, boolean AI, AI ai) {
	  int ammo = you.getAmmo();
	  if(checkCollision(target)) {
		  if(AI) {
			  ai.insert(20, 248);
		  }
		  if(ammo == 0 || ammo == 2 || ammo == 4) {
			  target.changeHealth(1);
			  changeHealth(10);
		  }
		  if(ammo == 1) changeHealth(10);
		  if(ammo == 3) {
			  changeHealth(10);
			  target.changeHealth(3);
		  }
	  }
	  else if(checkCollision(you)) {
		  if(ammo == 0 || ammo == 2 || ammo == 4) {
			  you.changeHealth(1);
			  changeHealth(10);
		  }
		  if(ammo == 1) changeHealth(10);
		  if(ammo == 3) {
			  changeHealth(10);
			  you.changeHealth(3);
		  }
	  }
	  else if(checkCollision(tiles)) {
		  TileObject tile = getCollision(tiles);
		  if(AI) {
			  ai.insert((int)tile.getX(),(int)tile.getY());
		  }
		  if(ammo == 2) {
			  changeHealth(4);
			  tile.explosion();
			  tiles.update();
		  }
		  else if(ammo == 3) {
			  changeHealth(10);
		  }
		  else {
			  if(ammo == 0 || ammo == 4) changeHealth(10);
			  else if(ammo == 1) changeHealth(1);
			  tile.setExist(false);
			  tile.updateNeighbours();
			  tiles.update();
		  }
	  }
	  
  }
  
  // As before but no AI
  public void checkColl(TankObject you,TankObject target, Map tiles) {
	  int ammo = you.getAmmo();
	  if(checkCollision(target)) {
		  if(ammo == 0 || ammo == 2 || ammo == 4) {
			  target.changeHealth(1);
			  changeHealth(10);
		  }
		  if(ammo == 1) changeHealth(10);
		  if(ammo == 3) {
			  changeHealth(10);
			  target.changeHealth(3);
		  }
	  }
	  else if(checkCollision(you)) {
		  if(ammo == 0 || ammo == 2 || ammo == 4) {
			  you.changeHealth(1);
			  changeHealth(10);
		  }
		  if(ammo == 1) changeHealth(10);
		  if(ammo == 3) {
			  changeHealth(10);
			  you.changeHealth(3);
		  }
	  }
	  else if(checkCollision(tiles)) {
		  TileObject tile = getCollision(tiles);
		  if(ammo == 2) {
			  changeHealth(4);
			  tile.explosion();
			  tiles.update();
		  }
		  else if(ammo == 3) {
			  changeHealth(10);
		  }
		  else {
			  if(ammo == 0 || ammo == 4) changeHealth(10);
			  else if(ammo == 1) changeHealth(1);
			  tile.setExist(false);
			  tile.updateNeighbours();
			  tiles.update();
		  }
	  }
	  
  }
  
  // balls starting position changes
  public void changeSide(){
	  if(this.xi == 830){
		  this.xi = 44;
		  this.yi = 303;
	  }
	  else{
		  this.xi = 830;
		  this.yi = 303;
	  }
  }
  
  // change players turn
  public void switchTurn(){
      if (who == 1){
    	  who = -1;
      }
      else{
    	  who = 1;
    	 
      }
  }
  // whos turn is it?
  public int getWho(){
	  return this.who;
  }
}
